Marketplace API - Authentication Guide
Learn how to authenticate your requests to the ATOM Public Marketplace API.
Overview
The Marketplace API supports two authentication methods:
- **API Keys** - Simple, recommended for server-side applications
- **OAuth 2.0** - User-specific authorization, recommended for client applications
Choose the method that best fits your use case.
---
API Key Authentication
What are API Keys?
API keys are static tokens that identify your application or tenant. They're ideal for:
- Server-side applications
- Background jobs
- Integrations that don't require user-specific actions
- Testing and development
Getting Your API Key
- Log in to your ATOM account at https://atomagentos.com
- Navigate to **Settings** → **API Keys**
- Click **Generate New Key**
- Enter a name for your key (e.g., "Production Integration")
- Select the scope:
read- Browse marketplace onlyread_write- Browse + submit skills, rate/review
- Click **Generate**
- Copy your key (format:
atom_pub_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
⚠️ **Important:** Store your API key securely. You won't be able to see it again after leaving the page.
Using Your API Key
Include your API key in the X-API-Key header:
curl -X POST "https://api.atomagentos.com/api/public/v1/marketplace/submit" \
-H "X-API-Key: atom_pub_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"name": "My Skill", ...}'API Key Security Best Practices
✅ **DO:**
- Store API keys in environment variables
- Use different keys for development and production
- Rotate keys regularly (every 90 days)
- Monitor key usage in your dashboard
- Restrict key scope to minimum required permissions
❌ **DON'T:**
- Commit API keys to version control
- Include API keys in client-side JavaScript
- Share API keys via email or chat
- Use production keys in development environments
Environment Variables
# .env file
ATOM_MARKETPLACE_API_KEY=atom_pub_YOUR_KEY_HERE// JavaScript/Node.js
const apiKey = process.env.ATOM_MARKETPLACE_API_KEY;
const response = await fetch(url, {
headers: {
'X-API-Key': apiKey
}
});# Python
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv('ATOM_MARKETPLACE_API_KEY')
headers = {
'X-API-Key': api_key
}Revoking an API Key
If a key is compromised or no longer needed:
- Navigate to **Settings** → **API Keys**
- Find the key you want to revoke
- Click **Revoke**
- Confirm the action
⚠️ **Warning:** Revoked keys cannot be restored. You'll need to generate a new key and update your applications.
---
OAuth 2.0 Authentication
What is OAuth 2.0?
OAuth 2.0 is an authorization framework that enables applications to obtain limited access to user accounts. It's ideal for:
- Client-side applications (web, mobile)
- Applications that require user-specific actions
- Multi-tenant applications where users have their own ATOM accounts
OAuth 2.0 Flow
The Marketplace API uses the **Authorization Code** flow with PKCE (Proof Key for Code Exchange).
Step 1: Register Your Application
- Contact api-support@atomagentos.com to register your OAuth application
- Provide:
- Application name
- Redirect URIs (where users are sent after authorization)
- Application type (web, mobile, desktop)
- Receive your
client_idandclient_secret
Step 2: Request Authorization
Redirect the user to the authorization endpoint:
https://atomagentos.com/oauth/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https://your-app.com/callback&
scope=marketplace:read+marketplace:write&
state=RANDOM_STATE_STRING&
code_challenge=CODE_CHALLENGE&
code_challenge_method=S256**Parameters:**
| Parameter | Description |
|---|---|
response_type | Must be code |
client_id | Your application's client ID |
redirect_uri | Where to redirect after authorization |
scope | Permissions requested (space-separated) |
state | Random string to prevent CSRF attacks |
code_challenge | PKCE code challenge (base64url-encoded SHA-256 of code verifier) |
code_challenge_method | Must be S256 |
**Scopes:**
| Scope | Description |
|---|---|
marketplace:read | Browse marketplace skills |
marketplace:write | Submit skills, rate/review |
Step 3: Handle Authorization Callback
After the user approves your request, they'll be redirected to your redirect_uri with an authorization code:
https://your-app.com/callback?
code=AUTHORIZATION_CODE&
state=RANDOM_STATE_STRINGVerify the state parameter matches what you sent in Step 2.
Step 4: Exchange Code for Access Token
POST to the token endpoint:
curl -X POST "https://api.atomagentos.com/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "AUTHORIZATION_CODE",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "https://your-app.com/callback",
"code_verifier": "CODE_VERIFIER"
}'**Response:**
{
"access_token": "ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH_TOKEN",
"scope": "marketplace:read marketplace:write"
}Step 5: Use Access Token
Include the access token in the Authorization header:
curl -X GET "https://api.atomagentos.com/api/public/v1/marketplace/skills" \
-H "Authorization: Bearer ACCESS_TOKEN"Step 6: Refresh Access Token
Access tokens expire after 1 hour. Use the refresh token to get a new one:
curl -X POST "https://api.atomagentos.com/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "REFRESH_TOKEN",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}'OAuth 2.0 Example (Node.js)
const crypto = require('crypto');
const express = require('express');
const axios = require('axios');
const app = express();
const PORT = 3000;
// OAuth configuration
const config = {
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
redirectUri: 'http://localhost:3000/callback',
authEndpoint: 'https://atomagentos.com/oauth/authorize',
tokenEndpoint: 'https://api.atomagentos.com/oauth/token'
};
// Generate PKCE code verifier and challenge
function generatePKCE() {
const verifier = crypto.randomBytes(32).toString('base64url');
const challenge = crypto.createHash('sha256')
.update(verifier)
.digest('base64url');
return { verifier, challenge };
}
// Step 1: Redirect to authorization endpoint
app.get('/auth', (req, res) => {
const { verifier, challenge } = generatePKCE();
const state = crypto.randomBytes(16).toString('hex');
// Store verifier and state in session
req.session.pkceVerifier = verifier;
req.session.state = state;
const authUrl = `${config.authEndpoint}?` +
`response_type=code&` +
`client_id=${config.clientId}&` +
`redirect_uri=${encodeURIComponent(config.redirectUri)}&` +
`scope=marketplace:read+marketplace:write&` +
`state=${state}&` +
`code_challenge=${challenge}&` +
`code_challenge_method=S256`;
res.redirect(authUrl);
});
// Step 2: Handle callback
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
// Verify state
if (state !== req.session.state) {
return res.status(400).send('Invalid state');
}
try {
// Step 3: Exchange code for access token
const tokenResponse = await axios.post(config.tokenEndpoint, {
grant_type: 'authorization_code',
code: code,
client_id: config.clientId,
client_secret: config.clientSecret,
redirect_uri: config.redirectUri,
code_verifier: req.session.pkceVerifier
});
const { access_token, refresh_token } = tokenResponse.data;
// Store tokens securely
req.session.accessToken = access_token;
req.session.refreshToken = refresh_token;
res.send('Authentication successful!');
} catch (error) {
console.error('Error exchanging code for token:', error);
res.status(500).send('Authentication failed');
}
});
// Use access token to call API
app.get('/api/skills', async (req, res) => {
try {
const response = await axios.get(
'https://api.atomagentos.com/api/public/v1/marketplace/skills',
{
headers: {
Authorization: `Bearer ${req.session.accessToken}`
}
}
);
res.json(response.data);
} catch (error) {
res.status(500).send('API request failed');
}
});
app.listen(PORT, () => {
console.log(`OAuth server running on http://localhost:${PORT}`);
});---
Choosing Between API Keys and OAuth
| Factor | API Key | OAuth 2.0 |
|---|---|---|
| **Use Case** | Server-side integrations | Client-side applications |
| **User Context** | Application-level | User-specific |
| **Security** | Static secret, keep secret | Time-limited tokens |
| **Setup** | Simple, instant | Requires registration |
| **Rate Limits** | 300 req/min | 600 req/min |
| **Best For** | Backend services, cron jobs | Web/mobile apps |
When to Use API Keys
✅ Server-side applications
✅ Background jobs and cron tasks
✅ Internal integrations
✅ Testing and development
✅ Single-tenant applications
When to Use OAuth 2.0
✅ Client-side web applications
✅ Mobile applications
✅ Multi-tenant applications
✅ Applications requiring user-specific actions
✅ Applications where users have their own ATOM accounts
---
Rate Limits by Authentication Method
| Method | Rate Limit |
|---|---|
| No authentication | 60 req/min, 1,000 req/day |
| API Key | 300 req/min, 10,000 req/day |
| OAuth 2.0 | 600 req/min, 50,000 req/day |
Higher rate limits are available for enterprise plans. Contact sales@atomagentos.com for details.
---
Troubleshooting
Common API Key Issues
**Error:** INVALID_API_KEY
**Solutions:**
- Verify the key is copied correctly (no extra spaces)
- Check that the key hasn't been revoked
- Ensure the key has the required scope
Common OAuth Issues
**Error:** invalid_grant
**Solutions:**
- Authorization code has expired (use within 10 minutes)
- Authorization code already used (codes are single-use)
- Redirect URI doesn't match registered URI
**Error:** invalid_client
**Solutions:**
- Verify client_id and client_secret are correct
- Ensure application is registered and active
Testing Authentication
# Test API key
curl -H "X-API-Key: atom_pub_YOUR_KEY" \
"https://api.atomagentos.com/api/public/v1/marketplace/categories"
# Test OAuth token
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
"https://api.atomagentos.com/api/public/v1/marketplace/categories"---
Security Checklist
- [ ] API keys stored in environment variables
- [ ] API keys never committed to version control
- [ ] OAuth secrets stored securely
- [ ] HTTPS always used for API requests
- [ ] State parameter validated in OAuth flow
- [ ] PKCE used for public clients
- [ ] Tokens stored securely (HttpOnly cookies for web, Keychain/Keystore for mobile)
- [ ] Access tokens refreshed before expiration
- [ ] API keys rotated regularly
- [ ] Unused keys/revoked immediately
---
Support
Need help with authentication?
- **Documentation:** https://atomagentos.com/docs/marketplace
- **Email:** api-support@atomagentos.com
- **Status Page:** https://atomagentos.com/status
---
**Ready to authenticate?** Get your API key or register your OAuth app.